"----------------------------------------------------------------
" New Filetypes
""""""""""""""""""""""""
au BufNewFile,BufRead *.h setf c

"----------------------------------------------------------------
" Common
""""""""""""""""""""""""
set fileencodings=utf-8,gb18030   " 兼容txt
set nocompatible                  " 关闭 vi 兼容模式
syntax on                         " 自动语法高亮
colorscheme atom-dark-256         " 设定配色方案
set number                        " 显示行号
"set number relativenumber         " 显示相对行号
set cursorline                    " 突出显示当前行
set ruler                         " 打开状态栏标尺
set tabstop=4                     " 设定 tab 长度为 4
set softtabstop=4                 " 使得按退格键时可以一次删掉 4 个空格
set shiftwidth=4                  " 设定 > 命令移动时的宽度为 4
set expandtab
set nobackup                      " 覆盖文件时不备份
set autochdir                     " 自动切换当前目录为当前文件所在的目录
filetype plugin indent on         " 开启插件
set smartindent                   " 开启新行时使用智能自动缩进
set backupcopy=yes                " 设置备份时的行为为覆盖
set ignorecase smartcase          " 搜索时忽略大小写，但在有一个或以上大写字母时仍保持对大小写敏感
set nowrapscan                    " 禁止在搜索到文件两端时重新搜索
set incsearch                     " 输入搜索内容时就显示搜索结果
set hlsearch                      " 搜索时高亮显示被找到的文本
set noerrorbells                  " 关闭错误信息响铃
set novisualbell                  " 关闭使用可视响铃代替呼叫
set t_vb=                         " 置空错误铃声的终端代码
"set showmatch                    " 插入括号时，短暂地跳转到匹配的对应括号
"set matchtime=1                  " 短暂跳转到匹配括号的时间
set magic                         " 设置魔术
set hidden                        " 允许在有未保存的修改时切换缓冲区，此时的修改由 vim 负责保存
set backspace=indent,eol,start    " 不设定在插入状态无法用退格键和 Delete 键删除回车符
set laststatus=2                  " 显示状态栏 (默认值为 1, 无法显示状态栏)
set cmdheight=1                   " 设定状态栏命令行的行数为 1
"set showtabline=2                " 显示标签栏
"set mouse=a                      " 开启鼠标模式
set guifont=YaHei\ Consolas\ Hybrid\ 12
set guioptions-=T                     " 隐藏工具栏
set guioptions-=m                     " 隐藏菜单栏
set guioptions-=L                     " 隐藏左侧滚动条
set guioptions-=r                     " 隐藏右侧滚动条

"----------------------------------------------------------------
"Status Line
""""""""""""""""""""""""
set statusline=%F                 " 文件的路径
set statusline+=%=                " 切换到右边
set statusline+=%{&fileencoding}  " 文件的编码
set statusline+=\                 " 分隔符
set statusline+=%c                " 当前列
set statusline+=\,                " 分隔符
set statusline+=%l                " 当前行
set statusline+=/                 " 分隔符
set statusline+=%L                " 总行数
set statusline+=\                 " 分隔符
set statusline+=%P                " 当前位置

"----------------------------------------------------------------
" Vim Shotcuts
""""""""""""""""""""""""
inoremap <F3> <Esc>:NERDTreeToggle<CR>
nnoremap <F3> :NERDTreeToggle<CR>

nnoremap <C-w><C-n> :tabp<CR>
nnoremap <C-w>n :tabn<CR>
nnoremap <C-w><C-l> :vertical resize +2<CR>
nnoremap <C-w><C-h> :vertical resize -2<CR>
nnoremap <C-w><C-j> :resize +2<CR>
nnoremap <C-w><C-k> :resize -2<CR>

au Syntax python set makeprg=python3\ -u\ %\ 
au Syntax go set makeprg=go\ install\ 
au Syntax lua set makeprg=lua5.1\ %\ 
au Syntax sh set makeprg=bash\ %\ 
au Syntax c,python,go,lua,sh nnoremap <F7> :w!<CR><CR>:execute "normal! ".QuickFix()<CR>

au Syntax c,go nnoremap e :cn<CR>
au Syntax c,go nnoremap E :cp<CR>
au Syntax go nnoremap H :!go doc <cword><CR>
au Syntax python nnoremap H :!pydoc3 <cword><CR>

"----------------------------------------------------------------
" Fold
""""""""""""""""""""""""
set fdm=marker
set foldmarker=<<FOLD<<,>>FOLD>>
nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR>

"----------------------------------------------------------------
" Complement
""""""""""""""""""""""""
" HTML
au Syntax html,css,javascript,xml inoremap ><space> ><Esc>%lyiwh%a</<Esc>pa><Esc>%i
au Syntax html,css,javascript,xml inoremap ><CR> ><Esc>%lyiwo</<Esc>pa><Esc>^d0k^y0j0Pk$
au Syntax html,css,javascript,xml inoremap {<CR> <Esc>:s/ *$//g<CR>:nohls<CR>A {<CR><BS>}<ESC>O
au Syntax html,css,javascript,xml inoremap ;<CR> <Esc>A;<CR>
" PHP
au Syntax php inoremap ><space> ><Esc>%lyiwh%a</<Esc>pa><Esc>%i
au Syntax php inoremap ><CR> ><Esc>%lyiwo</<Esc>pa><Esc>^d0k^y0j0Pk$
au Syntax php inoremap >p <?php  ?><Esc>2hi
au Syntax php inoremap >P <?php<CR>?><Esc>O
au Syntax php inoremap #I include '';<Esc>hi
au Syntax php inoremap #R require '';<Esc>hi
au Syntax php inoremap ;<CR> <Esc>A;<CR>
" SQL
au Syntax sql,plsql inoremap #I IF  THEN<CR>END IF;<ESC>khhhi
au Syntax sql,plsql inoremap #C CASE <CR>WHEN THEN<CR>ELSE<CR>END CASE;<ESC>kkkA
au Syntax sql,plsql inoremap #L LOOP<CR>END LOOP;<ESC>O
au Syntax sql,plsql inoremap #P DBMS_OUTPUT.PUT_LINE();<ESC>hi
au Syntax sql,plsql inoremap ;<CR> <Esc>A;<CR>
" C
au Syntax c inoremap #< #include<><Esc>i
au Syntax c inoremap #" #include ""<Esc>i
au Syntax c inoremap #M int main(int argc,char *argv[]){<CR>return 0;<CR>}<Esc>kO
au Syntax c inoremap {<CR> <Esc>:s/ *$//g<CR>:nohls<CR>A{<CR>}<ESC>O
au Syntax c inoremap ;<CR> <Esc>A;<CR>
" GO
au Syntax go inoremap {<CR> <Esc>:s/ *$//g<CR>:nohls<CR>A {<CR><BS>}<ESC>O
au Syntax go inoremap (<CR> <Esc>:s/ *$//g<CR>:nohls<CR>A (<CR>)<ESC>O
au Syntax go inoremap ;<CR> <Esc>A;<CR>
" SH
au Syntax sh inoremap {<CR> <Esc>:s/ *$//g<CR>:nohls<CR>A {<CR><BS>}<ESC>O
" PYTHON
au Syntax python inoremap :<CR> <C-r>=PythonColon()<CR>
" LUA
au Syntax lua inoremap #fu function ()<CR>end<Esc>Oreturn <Esc>k$F(i
au Syntax lua inoremap #if if  then<CR>end<Esc>k$F i
au Syntax lua inoremap #fo for  do<CR>end<Esc>k$F i
au Syntax lua inoremap #wh while  do<CR>end<Esc>k$F i

"----------------------------------------------------------------
" Operators
""""""""""""""""""""""""
" PHP
au Syntax php inoremap .= <space>.=<space>
au Syntax php inoremap === <space>===<space>
au Syntax php inoremap !== <space>!==<space>
au Syntax php inoremap <= <space><=<space>
au Syntax php inoremap >= <space>>=<space>
au Syntax php inoremap != <space>!=<space>
au Syntax php inoremap \|\| <space>\|\|<space>
au Syntax php inoremap == <space>==<space>
au Syntax php inoremap += <space>+=<space>
au Syntax php inoremap -= <space>-=<space>
au Syntax php inoremap *= <space>*=<space>
au Syntax php inoremap /= <space>/=<space>
au Syntax php inoremap && <space>&&<space>
" C
au Syntax c inoremap <= <space><=<space>
au Syntax c inoremap >= <space>>=<space>
au Syntax c inoremap != <space>!=<space>
au Syntax c inoremap \|\| <space>\|\|<space>
au Syntax c inoremap == <space>==<space>
au Syntax c inoremap += <space>+=<space>
au Syntax c inoremap -= <space>-=<space>
au Syntax c inoremap *= <space>*=<space>
au Syntax c inoremap /= <space>/=<space>
au Syntax c inoremap &= <space>&=<space>
au Syntax c inoremap \|= <space>\|=<space>
au Syntax c inoremap ~= <space>~=<space>
au Syntax c inoremap ^= <space>^=<space>
au Syntax c inoremap && <space>&&<space>
au Syntax c inoremap -> <space>-><space>
au Syntax c inoremap >> <space>>><space>
au Syntax c inoremap << <space><<<space>
" GO
au Syntax go inoremap := <space>:=<space>
au Syntax go inoremap <= <space><=<space>
au Syntax go inoremap >= <space>>=<space>
au Syntax go inoremap != <space>!=<space>
au Syntax go inoremap \|\| <space>\|\|<space>
au Syntax go inoremap == <space>==<space>
au Syntax go inoremap += <space>+=<space>
au Syntax go inoremap -= <space>-=<space>
au Syntax go inoremap *= <space>*=<space>
au Syntax go inoremap /= <space>/=<space>
au Syntax go inoremap &= <space>&=<space>
au Syntax go inoremap \|= <space>\|=<space>
au Syntax go inoremap ~= <space>~=<space>
au Syntax go inoremap ^= <space>^=<space>
au Syntax go inoremap && <space>&&<space>
au Syntax go inoremap -> <space>-><space>
au Syntax go inoremap >> <space>>><space>
au Syntax go inoremap << <space><<<space>
" PYTHON
au Syntax python inoremap <= <space><=<space>
au Syntax python inoremap >= <space>>=<space>
au Syntax python inoremap != <space>!=<space>
au Syntax python inoremap \|\| <space>\|\|<space>
au Syntax python inoremap == <space>==<space>
au Syntax python inoremap += <space>+=<space>
au Syntax python inoremap -= <space>-=<space>
au Syntax python inoremap *= <space>*=<space>
au Syntax python inoremap /= <space>/=<space>
au Syntax python inoremap &= <space>&=<space>
au Syntax python inoremap \|= <space>\|=<space>
au Syntax python inoremap ~= <space>~=<space>
au Syntax python inoremap ^= <space>^=<space>
au Syntax python inoremap && <space>&&<space>
" LUA
au Syntax lua inoremap <= <space><=<space>
au Syntax lua inoremap >= <space>>=<space>
au Syntax lua inoremap != <space>!=<space>
au Syntax lua inoremap \|\| <space>\|\|<space>
au Syntax lua inoremap == <space>==<space>
au Syntax lua inoremap += <space>+=<space>
au Syntax lua inoremap -= <space>-=<space>
au Syntax lua inoremap *= <space>*=<space>
au Syntax lua inoremap /= <space>/=<space>
au Syntax lua inoremap &= <space>&=<space>
au Syntax lua inoremap \|= <space>\|=<space>
au Syntax lua inoremap ~= <space>~=<space>
au Syntax lua inoremap ^= <space>^=<space>
au Syntax lua inoremap && <space>&&<space>
" SQL
au Syntax sql,plsql inoremap := <space>:=<space>
au Syntax sql,plsql inoremap <= <space><=<space>
au Syntax sql,plsql inoremap >= <space>>=<space>
au Syntax sql,plsql inoremap != <space>!=<space>
au Syntax sql,plsql inoremap \|\| <space>\|\|<space>

"----------------------------------------------------------------
" Comments
""""""""""""""""""""""""
" Html
au Syntax html nnoremap - V
au Syntax html vnoremap - <Esc>:call setpos(".",[0,line("'<"),0,0])<CR>I<!--<Esc>:call setpos(".",[0,line("'>"),0,0])<CR>A--><Esc>
au Syntax html nnoremap == $?<!--<CR>4x/--><CR>3x:nohls<CR>
" Sql 
au Syntax sql,plsql nnoremap - 0<C-v>
au Syntax sql,plsql nnoremap = 0<C-v>
au Syntax sql,plsql vnoremap - I--<Esc>
au Syntax sql,plsql vnoremap = :s:--::<CR>:nohls<CR>0
" C
au Syntax c nnoremap - 0<C-v>
au Syntax c nnoremap = 0<C-v>
au Syntax c vnoremap - I//<Esc>
au Syntax c vnoremap = :s://::<CR><CR>:nohls<CR>0
au Syntax c nnoremap - 0<C-v>
au Syntax c nnoremap = 0<C-v>
" GO
au Syntax go nnoremap - 0<C-v>
au Syntax go nnoremap = 0<C-v>
au Syntax go vnoremap - I//<Esc>
au Syntax go vnoremap = :s://::<CR><CR>:nohls<CR>0
" LUA
au Syntax lua nnoremap - 0<C-v>
au Syntax lua nnoremap = 0<C-v>
au Syntax lua vnoremap - I--<Esc>
au Syntax lua vnoremap = :s:--::<CR>:nohls<CR>0

"-----------------------------------------------------------------
" Matching Pairs
"""""""""""""""""""""""""
inoremap " <c-r>=QuoteDelim('"')<CR>
inoremap ' <c-r>=QuoteDelim("'")<CR>
inoremap ( ()<Esc>i
inoremap ) <c-r>=ClosePair(')')<CR>
inoremap [ []<Esc>i
inoremap ] <c-r>=ClosePair(']')<CR>
inoremap { {}<Esc>i
inoremap } <c-r>=ClosePair('}')<CR>
au Syntax html,css,js,php,xml set mps+=<:>
au Syntax html,css,js,php,xml inoremap > <c-r>=ClosePair('>')<CR>
au Syntax vim inoremap " "

"------------------------------------------------------------------------------
" Ctags
"""""""""""""""""""""""
" C
au syntax c nnoremap <C-w>t <Esc>:let $SRC=input("Enter source dir:")<CR>
au syntax c nnoremap <C-w>T <Esc>:!ctags -R -f /tmp/c_sys_tags -I __THROW --extra=+f --languages=c --langmap=c:+.h --c-kinds=+px --fields=+aiKSz --exclude=/usr/include/c++ --exclude=/usr/include/libio.h /usr/include<CR><CR>
au syntax c set tags=/tmp/c_cur_tags,/tmp/c_sys_tags
au BufWrite *.c,*.h !ctags -R -f /tmp/c_cur_tags --extra=+f --languages=c --langmap=c:+.h --c-kinds=+px --fields=+aiKSz $SRC
" GO
"au syntax go nnoremap <C-w>t <Esc>:let $GOPATH=input("Enter GOPATH dir:")<CR>
au syntax go nnoremap <C-w>t <Esc>:!ctags -R -f /tmp/go_sys_tags --languages=Go /usr/lib/go/src<CR><CR>
au syntax go set tags=/tmp/go_cur_tags,/tmp/go_sys_tags
au BufWrite *.go !ctags -R -f /tmp/go_cur_tags --languages=Go $GOPATH
" PYTHON
au syntax python nnoremap <C-w>t <Esc>:let $SRC=input("Enter source dir:")<CR>
au syntax python nnoremap <C-w>T <Esc>:!ctags -R -f /tmp/python_sys_tags --languages=Python /usr/lib/python3.7<CR><CR>
au syntax python set tags=/tmp/python_cur_tags,/tmp/python_sys_tags
au BufWrite *.py !ctags -R -f /tmp/python_cur_tags --languages=python $SRC

"------------------------------------------------------------------------------
" Cscope
""""""""""""""""""""""""
set cst
set csto=1
set cscopequickfix=s-,g-,c-,d-,i-,t-,e-
"au BufNewFile,BufRead *.c,*.h nnoremap #SS <ESC>:cs add $SRC/cscope.out<CR>
"au BufWrite *.c,*.h !find $SRC -type f|cscope -bk -i -;mv cscope.out $SRC/cscope.out
"au BufNewFile,BufRead *.c,*.h nnoremap #CC <ESC>:!echo 'Generating cs tags ...';find $SRC -type f\|cscope -bk -i -;mv cscope.out $SRC<CR>
"nnoremap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR> "查找本C符号（跳过注释）
"nnoremap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR> "查找本定义
"nnoremap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR> "查找本函数调用的函数
"nnoremap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR> "查找调用本函数的函数
"nnoremap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR> "查找本字符串
"nnoremap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR> "查找本 egrep 模式
"nnoremap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR> "查找本文件
"nnoremap <C-_>i :cs find i <C-R>=expand("<cfile>")<CR><CR> "查找包含本文件的文件

"------------------------------------------------------------------------------
" NERDTree
"""""""""""""""""""""""
let NERDChristmasTree = 1
let NERDTreeAutoCenter = 1
let NERDTreeQuitOnOpen = 1
let NERDTreeShowBookmarks = 1
let NERDTreeHighlightCursorline = 1
let NERDTreeShowFiles = 1
let NERDTreeStatusline = 1
"let NERDTreeShowHidden=1
"let NERDTreeShowLineNumbers=1
"let NERDTreeWinSize=30
" t.......在新Tab中打开选中文件/书签，并跳到新Tab     
" T.......在新Tab中打开选中文件/书签，但不跳到新Tab   
" i.......split一个新窗口打开选中文件，并跳到该窗口   
" gi......split一个新窗口打开选中文件，但不跳到该窗口 
" s.......vsp一个新窗口打开选中文件，并跳到该窗口     
" gs......vsp一个新窗口打开选中文件，但不跳到该窗口   
" !.......执行当前文件                                
" O.......递归打开选中结点下的所有目录                
" x.......合拢选中结点的父目录                        
" X.......递归合拢选中结点下的所有目录                

"------------------------------------------------------------------------------
" Templates
"""""""""""""""""""""""
let g:enable_template=1
let g:template_dir="~/.vim/templates"

"------------------------------------------------------------------------------
" Functions
"""""""""""""""""""""""
"function QuickFix()
"    if exists('g:QuickFixState') && g:QuickFixState
"        if exists('g:asyncrun_status') && 'running' == g:asyncrun_status
"            return ":AsyncStop!\<CR>"
"        endif
"        let g:QuickFixState = 0
"        if 'c' == &filetype
"            return ":cclose\<CR>:make clean\<CR>\<CR>"
"        elseif 'go' == &filetype
"            return ":cclose\<CR>:!go clean\<CR>\<CR>"
"        else
"            return ":cclose\<CR>"
"        endif
"    else
"        let g:QuickFixState = 1
"	    if 0 <= index(['c', 'python', 'go', 'lua', 'sh'], &filetype)
"            let b:argvs = input("Enter arguments:")
"            if matchstr(v:version, '^8')
"                return ":copen 15\<CR>\<C-w>k:AsyncRun ".&makeprg.b:argvs."\<CR>"
"            else
"                return ":make! ".b:argvs."\<CR>\<CR>:copen 15\<CR>\<C-w>k"
"            endif
"        else
"            let g:QuickFixState = 0
"            return "\<Esc>"
"        endif
"    endif
"endf

"function PythonColon()
"	let KeyWords = ['if', 'elif', 'else', 'for', 'while', 'class', 'def', 'with', 'try', 'except', 'finally']
"	let FirstWord = split(getline('.'))[0]
"	if FirstWord == 'try'
"		return "\<Esc>A:\<CR>except Exception, e:\<Esc><<O"
"	elseif 0 <= index(KeyWords, FirstWord)
"		return "\<Esc>A:\<CR>"
"	endif
"endf

"function ClosePair(char)
"	if getline('.')[col('.') - 1] == a:char
"		return "\<Right>"
"	else
"		return a:char
"	endif
"endf

"function QuoteDelim(char)
"    let line = getline('.')
"    let col = col('.')
"    if line[col - 2] == "\\"
"        return a:char
"    elseif line[col - 1] == a:char
"        return "\<Right>"
"    else
"        return a:char.a:char."\<Left>"
"    endif
"endf

"------------------------------------------------------------------------------
"------------------------------------------------------------------------------
